package com.bsh.serviceImpl;

import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.bsh.api.ApiUtils;
import com.bsh.api.Exception.ApiException;
import com.bsh.api.params.DtoSendSms;
import com.bsh.mybatis.model.User;
import com.bsh.mybatis.model.VerifySms;
import com.bsh.repository.DaoMobileVerifyCode;
import com.bsh.repository.DaoSysConfig;
import com.bsh.repository.DaoVerifySms;
import com.bsh.service.ApiSmsService;
import com.bsh.service.SmsService;
import com.bsh.service.UserService;
import com.bsh.utils.ApiMessage;
import com.bsh.utils.Constants;
import com.bsh.utils.Des3Utils;

@Service
@Transactional
public class ApiSmsServiceImpl implements ApiSmsService {
	private static Logger log = LoggerFactory.getLogger(ApiSmsServiceImpl.class);
	@Autowired
	SmsService smsServ;
	@Autowired
	UserService servUser;
	@Autowired
	DaoMobileVerifyCode mobileVerifyCodeDao;
	@Autowired
	DaoSysConfig sysDao;
	@Autowired
	DaoVerifySms verifyDao;

	@Override
	public ApiMessage sendSms(JSONObject dto) throws ApiException {
		ApiMessage msg = null;
		String type = dto.getString("type");
		switch (type) {
		case "forgetPassword":
		case "securitySetting":
		case "register":
			break;
		default:
			throw new ApiException("400", "未知类型错误");
		}

		if (ApiUtils.objIsEmpty(dto.getString("mobile"))) {
			throw new ApiException("400", "手机号不能为空");
		}
		if (ApiUtils.objIsEmpty(dto.getString("type"))) {
			throw new ApiException("400", "短信验证码类型不能为空");
		}

		if (ApiUtils.objIsEmpty(dto.getString("uuid"))) {
			throw new ApiException("400", "uuid不能为空");
		}
		String ip = ApiUtils.objIsNotEmpty(dto.getString("req_ip")) ? dto.getString("req_ip") : dto.getString("ip");

		// 图片验证码为空
		if (ApiUtils.objIsEmpty(dto.getString("verifyCode"))) {
			// 实名认证需要输入图片验证码
			if (type.equals("securitySetting")) {
				throw new ApiException("400", "图片验证码不能为空");
			}
			// 查询ip访问限制次数
			//Integer ipDevLimit = sysDao.getIpMaxIPRegDaily();
			Integer ipDevLimit = sysDao.findSysKey("max_ip_reg_daily");
			// 判断ip
			if (ApiUtils.objIsNotEmpty(ip)) {
				int ipTimes = mobileVerifyCodeDao.checkIpTimes(ip);
				if (ApiUtils.objIsNotEmpty(ipDevLimit) && ipTimes >= ipDevLimit) {
					log.error("ip：" + ip + "||发送次数：" + ipTimes + "||限制次数：" + ipDevLimit);
					throw new ApiException("108", "需要图片验证码");
				}
			}
			// 判断 设备号
			if (ApiUtils.objIsNotEmpty(dto.getString("deviceNum"))) {
				int devTimes = mobileVerifyCodeDao.checkDevTimes(dto.getString("deviceNum"));
				if (ApiUtils.objIsNotEmpty(ipDevLimit) && devTimes >= ipDevLimit) {
					log.error("设备号：" + ipDevLimit + "||发送次数：" + devTimes + "||限制次数：" + ipDevLimit);
					throw new ApiException("108", "需要图片验证码");
				}
			}
		}
		// 图片验证码非空
		else {
			// 根据uuid查询验证码
			VerifySms verifySms = verifyDao.selectByUuid(dto.getString("uuid"));
			if (ApiUtils.objIsEmpty(verifySms)) {
				throw new ApiException("400", "图片验证码不存在或已过期");
			}
			// 对比
			if (!verifySms.getVerifyCode().equals(dto.getString("verifyCode"))) {
				throw new ApiException("400", "图片验证码不正确");
			}
		}

		if (type.equals("forgetPassword") || type.equals("securitySetting")) {
			// 如果是找回密码验证是否已注册过的手机号
			User user = servUser.getUserByMobile(dto.getString("mobile"));
			if (ApiUtils.objIsEmpty(user)) {
				throw new ApiException("400", "手机号 " + dto.getString("mobile") + " 未注册");
			}
		}
		if (type.equals("register")) {
			// check phone number already exist
			User user = servUser.getUserByMobile(dto.getString("mobile"));
			if (ApiUtils.objIsNotEmpty(user)) {
				throw new ApiException("400", "手机号" + dto.getString("mobile") + "已经注册过，请登录");
			}
		}
		log.info("@@@发送短信:" + " register" + "用户名:" + dto.getString("mobile") + "  uuid:" + dto.getString("uuid")
				+ "  ip:" + ip + "  输入验证码:" + dto.getString("verifyCode") + " 时间：" + new Date());
		DtoSendSms result = smsServ.sendSmsVerifyCoed(dto.getString("mobile"), ip, dto.getString("type"),
				dto.getString("deviceNum"));
		if (result.getRes() > 0) {
			msg = new ApiMessage("200", "验证码发送成功");
		} else {
			msg = new ApiMessage("400", "发送失败");
		}
		return msg;
	}

	@Override
	public ApiMessage getUuid(JSONObject dto) throws ApiException {
		ApiMessage msg = new ApiMessage();
		if (ApiUtils.objIsEmpty(dto.getString("type"))) {
			throw new ApiException("400", "缺少短信验证码类型");
		}
		String type = dto.getString("type");
		switch (type) {
		case "forgetPassword":
		case "securitySetting":
		case "register":
			break;
		default:
			throw new ApiException("400", "未知类型错误");
		}
		String ip = ApiUtils.objIsNotEmpty(dto.getString("req_ip")) ? dto.getString("req_ip") : dto.getString("ip");

		// 生成uuid
		String uuid = ApiUtils.uuid();
		// 获取验证码
		String code = ApiUtils.getCharAndNumr(4);
		// 保存uuid信息
		VerifySms vs = new VerifySms();
		vs.setUuid(uuid);
		vs.setVerifyCode(code);
		vs.setType(dto.getString("type"));
		vs.setRemark(ip);
		int res = verifyDao.insertSelective(vs);
		if (res <= 0) {
			throw new ApiException("400", "生成uuid失败");
		}
		// 删除过期记录
		verifyDao.delete();
		// 返回
		Map<String, Object> verifyInfo = new HashMap<String, Object>();
		String encode = Des3Utils.encode(code);
		verifyInfo.put("uuid", uuid);
		verifyInfo.put("picUrl", dto.getString("server_ip") + "/res/ApiImgValidcode?code=" + URLEncoder.encode(encode));
		msg.setCode(Constants.REQ_SUCCESS);
		msg.setMessage(Constants.MSG_SUCCESS);
		JSONObject data = new JSONObject();
		data.put("verifyInfo", verifyInfo);
		msg.setData(data.toJSONString());
		return msg;
	}

}
